package com.xuelangyun.form.common.fileupload.controller;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletResponse;

import com.xuelangyun.form.common.cache.annotation.TrCacheConfig;
import com.xuelangyun.form.common.exception.DyformException;
import com.xuelangyun.form.common.fileupload.GsFileStorage;
import com.xuelangyun.form.common.fileupload.entity.UploadFileInfoEntity;
import com.xuelangyun.form.common.fileupload.service.UploadFileInfoService;
import com.xuelangyun.form.common.utils.R;
import com.xuelangyun.form.common.utils.SpringContextUtils;
import org.apache.commons.lang.StringUtils;
import org.csource.common.MyException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;


@Controller
@RequestMapping("/file")
@Api(value = "文件-通用", tags = {"文件-通用"})
public class FileUploadController {
 
  @Autowired
  private UploadFileInfoService uploadService;
   
  @Value("${dyform.upload.type}")
  private String uploadType ;
  
 
  
  private GsFileStorage gsFileStorage;
  
  /*
   * 允许被上传得文件类型
   */ 
  @TrCacheConfig("'upload_allow_types'")
  private Set<String> uploadTypes() {
//	  String key = "upload_allow_types" ;
//	  if(redisUtils.containKey(key)) {
//		  return redisUtils.get(key, Set.class);
//	  }
	  
	  Set<String> types = new HashSet<>(); 
	    
	  String ts = "bmp,jpg,jpeg,png,xls,xlsx,doc,docx,pdf,mp4,wmv,zip,txt,csv" ;
	  
	  
	 
	  String[] ss = ts.split(",");
		  
	  types.addAll(Arrays.asList(ss));
		   
	 // redisUtils.set(key, types , 30 * 60);
	  
	  return types ;
  }
   
  
 
//	@SysLog(value="上传文件",system = SysModule.sys)
	@PostMapping("/upload")
	@ResponseBody
	@ApiOperation("上传文件,返回文件的最终浏览地址-PC/APP")
	@ApiResponses(value = {
            @ApiResponse(code = 0, message = "上传成功"),
            @ApiResponse(code = 1, message = "该上传文件类型不支持"),
            @ApiResponse(code = 2, message = "上传失败")
    })
	public R<Object> fileUpload(MultipartFile  file) throws Exception {
		
		// 获取文件名后缀 ,判断��件类型
		String filename = file.getOriginalFilename();
		
		String suffix = com.xuelangyun.form.common.utils.StringUtils.getSuffixName(filename);
		
		// 判断是否再要求得范围内
		Set<String> types = uploadTypes();
		if(!types.contains(suffix.toLowerCase())) {
			return   R.error("该上传文件类型不支持.");
		}
		
		
		GsFileStorage altFile = getFileStorage() ;// GsFileStorage.getFileUtil();
		
		UploadFileInfoEntity entity = altFile.uploadFile(file);
		 if(entity == null) {
			 //  throw new Exception("上传失败");
			  return R.error("上传失败");
		  }
		 
		 // 插入数据库
		 uploadService.insert(entity);
		
		 Map<String, Object> map = new HashMap<>();
		 map.put("id", entity.getId());
		 map.put("url", entity.getFileUrl());
		 
		  return R.ok().setData(map);
			 
	}

	
/*	@RequestMapping("/list")
	@ResponseBody
	public R  getFileListInfo(@RequestParam Map<String, Object> params) {
		PageUtils page =ztbAttachmentService.queryPage(params);
		return R.ok().put("page", page);
	}*/
	
	/**
	 * 删除文件  这里为真实删除
	 * @param id
	 */
	@RequestMapping("/delete")
	@ResponseBody
	public R<Object> deleteFile(String id) {
		if(id == null) {
			return R.error("文件不存在");
		}
		
		UploadFileInfoEntity ment =  uploadService.getById(id);
		
		 if(ment == null) {
			 return R.error("文件不存在");
		 }
		 
		 //AltFileUtils altFile = AltFileUtils.getFileUtil();
		 
		//boolean res = altFile.deleteFile(ment);
		 
	 	
		/*if(res ) {
			
			// 数据库删除
			uploadService.removeById(id);
			
			return R.ok().setData(ment);
		} else {
			return R.error("删除失败");
		}*/
		return R.ok().setData(ment);
	}
	
	@GetMapping("/list")
	@ResponseBody
	@ApiOperation("根据文件ID集合返回文件实际信息") 
	@ApiResponses(value = { @ApiResponse(code = 0, message = "查询成功" , response=UploadFileInfoEntity.class) })
	public R<Object> list(@ApiParam(required=true,value="文件集合,逗号分隔") @RequestParam("ids")  String ids){
		
		if(ids == null || ids.isEmpty()) {
			return R.error("当前不存在文件");
		}
		
		String[] ss = ids.split(",");
		 
		Collection<UploadFileInfoEntity> list = uploadService.selectList(ss);
		 
		return R.ok().setData( list);
	}
	  
	
	@RequestMapping("/fileDown")
	public void  fileDowload(HttpServletResponse response,String uuid) throws MyException, IOException  {
		//
		if(StringUtils.isEmpty(uuid)) {
			return ;
		}

        //1.设置文件ContentType类型，这样设置，会自动判断下载文件类型   
        response.setContentType("multipart/form-data");   
        //2.设置文件头：最后一个参数是设置下载文件名(假如我们叫a.pdf)   
        UploadFileInfoEntity ment =  uploadService.getById(uuid);
        // uuid 根据ID查询到文件的具体存储路径和文件名
         
        String name =ment.getOldFileName();
        // 非IE浏览器的处理：  
        name = new String(name.getBytes("UTF-8"), "ISO-8859-1");  
        response.setHeader("Content-disposition",String.format("attachment; filename=\"%s\"", name));  
        response.setContentType("multipart/form-data");   
        response.setCharacterEncoding("UTF-8");
        

		 GsFileStorage altFile = getFileStorage() ;// GsFileStorage.getFileUtil();
        
       //通过文件路径获得File对象(假如此路径中有一个download.pdf文件)   
        OutputStream os = response.getOutputStream();
        altFile.downFile(ment, os);
        	
        
                   		 
	}

	@SuppressWarnings("rawtypes")
	@GetMapping("/getFileUrl/{id}")
	@ResponseBody
	@ApiOperation("根据文件ID返回文件地址信息")
	@ApiResponses(value = { @ApiResponse(code = 0, message = "查询成功" , response=UploadFileInfoEntity.class) })
	public R<List> getFileUrl(@ApiParam(required=true,value="文件id") @PathVariable("id")  String id){
		List<String> list = uploadService.selectUrlList(id);
		return R.ok(List.class).setData( list);
	}

	@GetMapping("/getUploadFile/{id}")
	@ResponseBody
	@ApiOperation("根据文件ID返回文件地址信息")
	@ApiResponses(value = { @ApiResponse(code = 0, message = "查询成功" , response=UploadFileInfoEntity.class) })
	public R<String> getUploadFile(@ApiParam(required=true,value="文件id") @PathVariable("id")  String id){
		String url = null;
		UploadFileInfoEntity  uploadFileEntity = uploadService.selectFileEntity(id);
		if(uploadFileEntity!=null){
			url = uploadFileEntity.getFileUrl();
		}
		return R.ok(String.class).setData(url);
	}
	  

	GsFileStorage getFileStorage() {
		
		if(gsFileStorage != null) {
			return gsFileStorage;
		}
		
		Collection<GsFileStorage> list = SpringContextUtils.getBeanByType(GsFileStorage.class);
		for(GsFileStorage gf : list) {
			if(uploadType.equalsIgnoreCase(gf.getType())) {
				gsFileStorage = gf;
				break;
			}
		}
		
		if(gsFileStorage == null) {
			throw new DyformException("上传文件配置缺失");
		}
		
		return gsFileStorage;
	}
	
}
